package com.base.invoke.okhttp.interceptor;

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;

/**
 * 文件下载拦截器
 * @author coolpig
 * @date 2019-08-28
 */
public abstract class DownloadFileInterceptor implements Interceptor,DownloadFileProgressListener{
	//
	@Override
	public Response intercept(Chain chain) throws IOException {
		Response rsp = chain.proceed(chain.request());
	    return rsp.newBuilder()
	        .body(new DownloadFileProgressResponseBody(rsp.body(),this))
	        .build();
	}
	//
	public abstract void updateProgress(long downloadLenth, long totalLength, boolean isFinish);
	//
	public static class DownloadFileProgressResponseBody extends ResponseBody{
		private final ResponseBody responseBody;
	    private final DownloadFileProgressListener proListener;
	    private BufferedSource bufredSource;
	    //
	    public DownloadFileProgressResponseBody(ResponseBody body, DownloadFileProgressListener progressListener) {
            this.responseBody = body;
            this.proListener = progressListener;
        }
	    
		@Override
		public MediaType contentType() {
			return responseBody.contentType();
		}

		@Override
		public long contentLength() {
			return responseBody.contentLength();
		}

		@Override
		public BufferedSource source() {
			if (bufredSource == null) {
				bufredSource = Okio.buffer(getSourceInfo(responseBody.source()));
            }
            return bufredSource;
		}
		
		private Source getSourceInfo(Source sc) {
            return new ForwardingSource(sc) {
                long downLenth = 0L;

                @Override public long read(Buffer sink, long byteCount) throws IOException {
                    long bytesRead = super.read(sink, byteCount);
                    boolean isFinish=(bytesRead ==-1);
                    if(!isFinish){
						downLenth += bytesRead;
                    }
					proListener.updateProgress(downLenth, responseBody.contentLength(),isFinish);
                    return bytesRead;
                }
            };
        }
	}
}
